﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using JasRibbonApplicatie.Classes;

namespace JasRibbonApplicatie
{
    public class Queries
    {
        // uit DocumentatieERD: codes materiaal van m0000 tot mzzzz (ongevoelig voor hoofdletters)
        // gelijkaardig voor andere scancodes!
        public const int LENGTH_SCANCODES = 5;
        public const int AANTAL_DAGEN_IN_WEEK = 7;

        public enum Functie {
            Voorzitter,
            Secretaris,
            Penningmeester,
            Lid
        }

        public static jasEntities entities = new jasEntities();
        public static List<int> lijst = new List<int>();
        public static List<String> toebehorenNaamLijst = new List<String>();



        public static List<Aanvraag> GetAanvragen(List<Aanvraag.Statussen> statusFilter)
        {
            List<aanvragen> aanvragenLijst;
            List<int> status_ids = new List<int>();
            foreach (int stat in statusFilter) status_ids.Add(stat);

            if (status_ids.Count>0)
                aanvragenLijst = (from a in entities.aanvragen
                                  where status_ids.Contains(a.status_id)
                                  select a).ToList();
            else aanvragenLijst = entities.aanvragen.ToList();

            List<Aanvraag> av = new List<Aanvraag>();

            foreach (aanvragen a in aanvragenLijst)
            {
                av.Add(new Aanvraag(a.aanvraag_id, GetVerenigingById(a.vereniging_id),
                                    GetEvenementById(a.evenement_id), GetGebruikerById(a.gebruiker_id),
                                    GetMagazijnierByMagazijnierId(a.magazijnier_id_afhaling), GetMagazijnierByMagazijnierId(a.magazijnier_id_inlevering),
                                    a.geplande_afhaling, a.geplande_inlevering, a.status_id));
            }
            return av;
        }
        public static List<Aanvraag> GetAanvragenByOphaalDate(DateTime date)
        {
            var aanvragenQuery = from aanvraag in entities.aanvragen
                                 where aanvraag.geplande_afhaling.Value.Year.Equals(date.Year)
                                 && aanvraag.geplande_afhaling.Value.Month.Equals(date.Month)
                                 && aanvraag.geplande_afhaling.Value.Day.Equals(date.Day)
                                 select aanvraag;
            var aanvragenlijst = aanvragenQuery.ToList();

            List<Aanvraag> resultaatlijstAanvragen = new List<Aanvraag>();
            foreach (var aanvraag in aanvragenlijst)
            {
                resultaatlijstAanvragen.Add(new Aanvraag(aanvraag.aanvraag_id, GetVerenigingById(aanvraag.vereniging_id),
                                    GetEvenementById(aanvraag.evenement_id), GetGebruikerById(aanvraag.gebruiker_id),
                                    GetMagazijnierByMagazijnierId(aanvraag.magazijnier_id_afhaling), GetMagazijnierByMagazijnierId(aanvraag.magazijnier_id_inlevering),
                                    aanvraag.geplande_afhaling, aanvraag.geplande_inlevering, aanvraag.status_id));
            }

            return resultaatlijstAanvragen;
        }
        public static List<Aanvraag> GetAanvragenByInleverDate(DateTime date)
        {
            var aanvragenQuery = from aanvraag in entities.aanvragen
                                 where aanvraag.geplande_inlevering.Value.Year.Equals(date.Year)
                                 && aanvraag.geplande_inlevering.Value.Month.Equals(date.Month)
                                 && aanvraag.geplande_inlevering.Value.Day.Equals(date.Day)
                                 select aanvraag;
            var aanvragenlijst = aanvragenQuery.ToList();

            List<Aanvraag> resultaatlijstAanvragen = new List<Aanvraag>();
            foreach (var aanvraag in aanvragenlijst)
            {
                resultaatlijstAanvragen.Add(new Aanvraag(aanvraag.aanvraag_id, GetVerenigingById(aanvraag.vereniging_id),
                                    GetEvenementById(aanvraag.evenement_id), GetGebruikerById(aanvraag.gebruiker_id),
                                    GetMagazijnierByMagazijnierId(aanvraag.magazijnier_id_afhaling), GetMagazijnierByMagazijnierId(aanvraag.magazijnier_id_inlevering),
                                    aanvraag.geplande_afhaling, aanvraag.geplande_inlevering, aanvraag.status_id));
            }

            return resultaatlijstAanvragen;
        }
        public static List<Aanvraag> GetAanvragenPerWeekByOphaaldatum(DateTime datum)
        {
            List<Aanvraag> weeklijstAanvragen = new List<Aanvraag>();
            DayOfWeek weekdag = datum.DayOfWeek;
            // aanvragen worden per dag aan de lijst toegevoegd, beginnend met zondag, tot en met zaterdag (zie DayOfWeek voor de reden)
            for (int i = 0; i < AANTAL_DAGEN_IN_WEEK; i++)
            {
                DateTime dag = datum.AddDays(-((((int)weekdag) - i)));
                // vb: woe=3, zon=0         -(3-0)         = -3 dagen       (=> di => ma => zo)
                // vb: woe=3, zat=6         -(3-6) = -(-3) = +3 dagen       (=> do => vr => za)

                weeklijstAanvragen.AddRange(GetAanvragenByOphaalDate(dag));
            }
            return weeklijstAanvragen;
        }
        public static List<Aanvraag> GetAanvragenPerWeekByTerugbrengdatum(DateTime datum)
        {
            List<Aanvraag> weeklijstAanvragen = new List<Aanvraag>();
            DayOfWeek weekdag = datum.DayOfWeek;
            // aanvragen worden per dag aan de lijst toegevoegd, beginnend met zondag, tot en met zaterdag (zie DayOfWeek voor de reden)
            for (int i = 0; i < AANTAL_DAGEN_IN_WEEK; i++)
            {
                DateTime dag = datum.AddDays(-((((int)weekdag) - i)));
                // vb: woe=3, zon=0         -(3-0)         = -3 dagen       (=> di => ma => zo)
                // vb: woe=3, zat=6         -(3-6) = -(-3) = +3 dagen       (=> do => vr => za)

                weeklijstAanvragen.AddRange(GetAanvragenByInleverDate(dag));
            }
            return weeklijstAanvragen;
        }

        public static Aanvraag GetAanvraagById(int Aanvraag_id)
        {
            var av = (from a in entities.aanvragen
                      where a.aanvraag_id == Aanvraag_id
                      select a).First();

            return new Aanvraag(av.aanvraag_id, GetVerenigingById(av.vereniging_id),
                                     GetEvenementById(av.evenement_id), GetGebruikerById(av.gebruiker_id),
                                     GetMagazijnierByMagazijnierId(av.magazijnier_id_afhaling), GetMagazijnierByMagazijnierId(av.magazijnier_id_inlevering),
                                     av.geplande_afhaling, av.geplande_inlevering, av.status_id);
        }
        
        public static evenement GetEvenementById(int id)
        {
            var evenementQuery = from ev in entities.evenement
                                 where ev.evenement_id.Equals(id)
                                 select ev;
            return evenementQuery.First<evenement>();
        }
       
        public static Gebruiker GetGebruikerById(int id)
        {
            var query = from g in entities.gebruikers
                        where g.gebruiker_id.Equals(id)
                        select g;
            return new Gebruiker(query.First<gebruikers>());
        }

        public static List<Gebruiker> GetAllGebruikers()
        {
            var gebruikersQuery = from gebruikers in entities.gebruikers
                                  select gebruikers;
            List<Gebruiker> gebruiker = new List<Gebruiker>();
            foreach (gebruikers a in gebruikersQuery)
            {
                gebruiker.Add(new Gebruiker(a));
            }
            return gebruiker;
        }
        public static List<gebruikers> GetGebruikersByMagazijnierIds(List<int> magazijnierIds)
        {
            var gebruikerIdQuery = from mpersonen in entities.magazijniers
                                    where magazijnierIds.Contains(mpersonen.magazijnier_id)
                                    select mpersonen.gebruiker_id;
            List<int> gebruikerIds = gebruikerIdQuery.ToList();
            var gebruikerQuery = from personen in entities.gebruikers
                                 where gebruikerIds.Contains(personen.gebruiker_id)
                                 select personen;
            return gebruikerQuery.ToList();
        }

        // Summary:
        //      Takes all the magazijniers and beheerders from the database
        //
        // Returns:
        //      A list of users or null
        //
        public static List<gebruikers> GetAllLoginData()
        {
            List<gebruikers> personen = new List<gebruikers>();
            var magazijniersQuery = from magazijnPersonen in entities.magazijniers
                                    where magazijnPersonen.einde == null
                                    || ((magazijnPersonen.einde != null) && (magazijnPersonen.einde.Value.CompareTo(DateTime.Now) >= 0))
                                    select magazijnPersonen.magazijnier_id;

            personen.AddRange(GetGebruikersByMagazijnierIds(magazijniersQuery.ToList()));

            var beheerdersQuery = from beheerpersonen in entities.gebruikers
                                  where beheerpersonen.rechten_id.Equals(2)
                                  select beheerpersonen;
            personen.AddRange(beheerdersQuery.ToList());
            return personen;
        }
                
        public static List<ledenalgverg> GetAllLedenalgverg() {
            var ledenalgvergQuery = from ledenalgverg in entities. ledenalgverg
                                    select ledenalgverg;
            List<ledenalgverg> Leden = new List<ledenalgverg>();
            foreach (ledenalgverg a in ledenalgvergQuery)
            {
                Leden.Add(a);
            }
            return Leden;
        
        
        
        }
        
        public static Magazijnier GetMagazijnierById(int? id)
        {
            if (id != null)
            {
                var magazijnierQuery = from mag in entities.magazijniers
                                       where mag.magazijnier_id.Equals((int)id)
                                       select mag;
                magazijniers magazijnier = magazijnierQuery.First<magazijniers>();
                return new Magazijnier()
                {
                    MagazijnierId = magazijnier.magazijnier_id,
                    Gebruiker = GetGebruikerById(magazijnier.gebruiker_id),
                    Streepjescode = magazijnier.streepjescode,
                    Start = magazijnier.start,
                    Einde = magazijnier.einde
                };
            }
            else
            {
                return null;
            }
        }
        public static Magazijnier GetMagazijnierByGebruiker_id(int gebruikerId)
        {
            // een gebruiker kan meerdere malen voorkomen in de magazijnierstabel (meerdere keren kan hij/zij die functie uitoefenen doorheen de tijd)
            // daarom wordt de grootste startdatum genomen => query vereenvoudigd + fouten uit gehaald (eerst controlleren of er iets in zit en dan pas first nemen)

            var magazijnierQuery = from mag in entities.magazijniers
                                   where mag.gebruiker_id == gebruikerId
                                   orderby mag.start
                                   select mag;
            if(magazijnierQuery.Count()>0){
                magazijniers magazijnier = magazijnierQuery.First();

                Magazijnier magazijnierObject = new Magazijnier()
                {
                    MagazijnierId = magazijnier.magazijnier_id,
                    Streepjescode = magazijnier.streepjescode,
                    Gebruiker = GetGebruikerById(magazijnier.gebruiker_id),
                    Start = magazijnier.start,
                    Einde = magazijnier.einde
                };
                return magazijnierObject;
            }
            else
            {
                throw new ArgumentException("Deze gebruiker is geen magazijnier!");
            }

        }
        public static Magazijnier GetMagazijnierByMagazijnierId(int? id)
        {
            if (id != null)
            {
                var magazijnierQuery = from mag in entities.magazijniers
                                       where mag.magazijnier_id.Equals((int)id)
                                       select mag;
                magazijniers magazijnier = magazijnierQuery.First<magazijniers>();
                return new Magazijnier()
                {
                    MagazijnierId = magazijnier.magazijnier_id,
                    Gebruiker = GetGebruikerById(magazijnier.gebruiker_id),
                    Streepjescode = magazijnier.streepjescode,
                    Start = magazijnier.start,
                    Einde = magazijnier.einde
                };
            }
            else
            {
                return null;
            }
        }
        public static List<Magazijnier> GetMagazijniers()
        {
            var magazijnierQuery = from mag in entities.magazijniers
                                   select mag;
            var magazijnierlijst = magazijnierQuery.ToList();

            List<Magazijnier> mags = new List<Magazijnier>();

            foreach (var mag in magazijnierlijst)
            {
                mags.Add(new Magazijnier()
                {
                    MagazijnierId = mag.magazijnier_id,
                    Gebruiker = GetGebruikerById(mag.gebruiker_id),
                    Streepjescode = mag.streepjescode,
                    Start = mag.start,
                    Einde = mag.einde
                });
            }
            return mags;
        }
        // GetMagazijnierForDate wordt momenteel niet gebruikt???
        public static Magazijnier GetMagazijnierForDate(DateTime? datum)
        {
            if (datum != null)
            {
                var magid = from planning in entities.planningmagazijniers
                            where planning.datum.Year.Equals(datum.Value.Year)
                               && planning.datum.Month.Equals(datum.Value.Month)
                               && planning.datum.Day.Equals(datum.Value.Day)
                            select planning.magazijnier_id;
                if (magid.Count() > 0)
                    return GetMagazijnierByMagazijnierId(magid.First());
                else return null;
            }
            else
            {
                return null;
            }
        }
        public static List<PlanningMagazijnier> GetPlanningenForDate(DateTime? datum)
        {
            List<PlanningMagazijnier> planningen = new List<PlanningMagazijnier>();
            if (datum != null)
            {
                var planning = (from p in entities.planningmagazijniers
                                where p.datum.Year.Equals(datum.Value.Year)
                                      && p.datum.Month.Equals(datum.Value.Month)
                                      && p.datum.Day.Equals(datum.Value.Day)
                                select p).ToList();
                
                if (planning.Count() > 0)
                {
                    foreach (var p in planning)
                    {
                        planningen.Add(new PlanningMagazijnier(p));
                    }

                }
            }
            return planningen;
        }

        // GetMateriaalVolledig wordt momenteel niet gebruikt???
        public static List<Materiaal> GetMateriaalVolledig()
        {
            var materiaalQuery = from product in entities.materiaal
                                 select product;

            var materiaalLijst = new List<Materiaal>();
            foreach (materiaal mat in materiaalQuery)
            {

                Materiaal m = new Materiaal()
                {
                    Streepjescode = mat.streepjescode,
                    Materiaaltype = GetTypeMateriaalMetToebehorengByMateriaalTypeId(mat.materiaalType_id)
                };
                materiaalLijst.Add(m);
            }
            return materiaalLijst;
        }
 
        public static List<MateriaalBestelling> GetMateriaalBestellingenByAanvraagId(int aanvraag_id)
        {
            var materiaalBestellingenQuery = from materiaalbestelling in entities.materiaalbestellingen
                                             where materiaalbestelling.aanvraag_id.Equals(aanvraag_id)
                                             select materiaalbestelling;
            var materiaalBestellingenLijst = materiaalBestellingenQuery.ToList();

            List<MateriaalBestelling> resultaatlijst = new List<MateriaalBestelling>();
            foreach (var materiaalbestelling in materiaalBestellingenLijst)
            {
                resultaatlijst.Add(new MateriaalBestelling()
                    {
                        MateriaalBestelling_id = materiaalbestelling.materiaalBestelling_id,
                        Aanvraag_id = materiaalbestelling.aanvraag_id,
                        MateriaalType_id = materiaalbestelling.materiaalType_id,
                        AantalAangevraagd = materiaalbestelling.aantalAangevraagd,
                        AantalGoedgekeurd = materiaalbestelling.aantalGoedgekeurd
                    });
            }
            return resultaatlijst;
        }
        
        // GetMateriaalOntleningenByAanvraagId wordt momenteel niet gebruikt???
        public static List<ontleningen> GetMateriaalOntleningenByAanvraagId(int aanvraag_id)
        {
            var ontleningQuery = from item in entities.ontleningen
                                 where item.aanvraag_id.Equals(aanvraag_id)
                                 && item.streepjescode.ToLower().First().Equals('m')
                                 select item;
            return ontleningQuery.ToList();
        }
        public static bool IsProductNietUitgeleendMomenteel(String scancode)
        {
            var ontleningQuery = from entries in entities.ontleningen
                                 where entries.streepjescode.Equals(scancode)
                                 && entries.tijdstip_inlevering.Equals(DateTime.MinValue)
                                 select entries;

            var lijstOntleningen = ontleningQuery.ToList();
            if (lijstOntleningen.Count == 0)
            {
                return true;
            }
            return false;
        }

        public static List<PlanningMagazijnier> GetPlanningMagazijniersByMagazijnierIdAndDate(int magazijnierId, DateTime datum )
        {
            return Queries.GetPlanningMagazijniers().Where(a => (a.Magazijnier.MagazijnierId == magazijnierId) && (a.Datum == datum)).ToList<PlanningMagazijnier>();
        }

        public static List<PlanningMagazijnier> GetPlanningMagazijniersByDatum(DateTime date)
        {
            var query = from mag in entities.magazijniers
                        join geb in entities.gebruikers on mag.gebruiker_id equals geb.gebruiker_id
                        join planning in entities.planningmagazijniers on mag.magazijnier_id equals planning.magazijnier_id
                        where planning.datum.Year == date.Year &&
                              planning.datum.Month == date.Month &&
                              planning.datum.Day == date.Day
                        select new
                        {
                            geb,
                            mag,
                            planning
                        };

            List<PlanningMagazijnier> planningen = new List<PlanningMagazijnier>();
            foreach (var it in query)
            {
                Magazijnier magazijnier = new Magazijnier(it.mag, new Gebruiker(it.geb));
                PlanningMagazijnier planning = new PlanningMagazijnier(magazijnier, it.planning.datum);
                planningen.Add(planning);
            }
            return planningen;
        }

        public static List<PlanningMagazijnier> GetPlanningMagazijniersByGebruikersId(int gebruikerId)
        {
            return Queries.GetPlanningMagazijniers().Where(a => a.Magazijnier.Gebruiker.Gebruiker_id == gebruikerId).ToList<PlanningMagazijnier>();
        }

        public static List<PlanningMagazijnier> GetPlanningMagazijniers()
        {
            var query = from mag in entities.magazijniers
                        join geb in entities.gebruikers on mag.gebruiker_id equals geb.gebruiker_id
                        join planning in entities.planningmagazijniers on mag.magazijnier_id equals planning.magazijnier_id
                        select new
                        {
                            geb,
                            mag,
                            planning
                        };

            List<PlanningMagazijnier> users = new List<PlanningMagazijnier>();
            foreach (var it in query)
            {
                Magazijnier magazijnier = new Magazijnier(it.mag, new Gebruiker(it.geb));
                PlanningMagazijnier user = new PlanningMagazijnier(magazijnier, it.planning.datum);
                users.Add(user);
            }
            return users;
        }
        //methode bestaat reeds
        //public static List<PlanningMagazijnier> getPlanningMagazijniersByGebruikers_id(int gebruikersId)
        //{
        //    var query = from plan in entities.planningmagazijniers
        //                join mag in entities.magazijniers on plan.magazijnier_id equals mag.magazijnier_id
        //                where mag.gebruiker_id == gebruikersId
        //                select new PlanningMagazijnier(new Magazijnier()
        //                    {
        //                        MagazijnierId = mag.magazijnier_id,
        //                        Gebruiker = getGebruikerById(mag.gebruiker_id),
        //                        Streepjescode = mag.streepjescode,
        //                        Start = mag.start,
        //                        Einde = mag.einde
        //                    }, plan.datum);

        //    return query.ToList<PlanningMagazijnier>();
        //}

        public static postcodes GetPostcodeByPostcodeId(int Postcode_id)
        {
            var postcodeQuery = from p in entities.postcodes
                                where p.postc_id.Equals(Postcode_id)
                                select p;
            return postcodeQuery.First<postcodes>();
        }

        public static rechten GetRechtenById(int Rechten_id)
        {
            var query = from r in entities.rechten
                        where r.rechten_id.Equals(Rechten_id)
                        select r;
            if(query.Count()>0)
                return query.First();
            return null;
        }
        internal static void SetRechtenByGebruiker_id(int Gebruiker_id, int Rechten_id)
        {
            var query = from g in entities.gebruikers
                        where g.gebruiker_id== Gebruiker_id && g.rechten_id != Rechten_id
                        select g;
            if (query.Count() > 0)
            {
                var g = query.First();
                g.rechten_id = Rechten_id;
                entities.SaveChanges();
            }
        }
        public static List<rechten> GetAllRechten()
        {
            var query = from r in entities.rechten
                        select r;
            return query.ToList();
        }
        
        //public static List<int> GetToebehorenTypeId(int materiaalTypeId)
        //{
        //    lijst.Clear();
        //    var query = from m in entities.toebehorenmateriaal
        //                where m.materiaalType_id == materiaalTypeId
        //                select m.toebehorenType_id;
        //    foreach (var item in query)
        //    {
        //        lijst.Add(item);
        //    }
        //    return lijst;
        //}

        public static List<String> GetToebehorenNaam(int toebehorenType_id)
        {
            toebehorenNaamLijst.Clear();
            var query = from m in entities.toebehorentypes
                        where m.toebehorenType_id == toebehorenType_id
                        select m.naam;
            foreach (var item in query)
            {
                toebehorenNaamLijst.Add(item);
            }
            return toebehorenNaamLijst;
        }

        // GetAllLinkItems wordt momenteel niet gebruikt???
        // return materiaal, inclusief alle toebehoren...
        public static List<LinkItem> GetAllLinkItems()
        {
            List<LinkItem> myList = new List<LinkItem>();
            var query = from linkMateriaal in entities.toebehorenmateriaal
                        select linkMateriaal;
            var lijst = query.ToList();
            foreach (var item in lijst)
            {
                var materiaal = Queries.GetTypeMateriaalMetToebehorengByMateriaalTypeId(item.materiaalType_id);
                var toebehoren = Queries.GetToebehorenNaam(item.toebehorenType_id);
                myList.Add(new LinkItem(item.materiaalType_id, item.toebehorenType_id, materiaal.Naam, toebehoren.ToString(), item.aantal));
            }
            return myList;
        }

        public static List<TypeMateriaalMetToebehoren> GetAllTypeMateriaalMetToebehoren()
        {
            var materiaalQuery = from product in entities.materiaaltypes
                                 orderby product.type
                                 select product;
            var mq = materiaalQuery.ToList();
            List<TypeMateriaalMetToebehoren> allMateriaal = new List<TypeMateriaalMetToebehoren>();
            foreach (materiaaltypes m in mq)
            {
                // toebehoren ophalen, en ineens wegschrijven via constructor
                TypeMateriaalMetToebehoren materiaalVolledig = new TypeMateriaalMetToebehoren(GetToebehorenTypesByMateriaalTypeId(m.materiaalType_id))
                {
                    materiaalType_id = m.materiaalType_id,
                    Type = m.type,
                    Naam = m.naam,
                    Korte_naam = m.korte_naam,
                    Omschrijving = m.omschrijving,
                    Afbeelding = m.afbeelding,
                    File = m.file,
                    Waarborg = m.waarborg,
                    WaarborgExtraStuks = m.waarborgExtraStuks,
                    Dagprijs = m.dagprijs
                };
                allMateriaal.Add(materiaalVolledig);
            }
            return allMateriaal;
        }

        public static TypeMateriaalMetToebehoren GetTypeMateriaalMetToebehorengByMateriaalTypeId(int materiaalType_id)
        {
            var materiaalQuery = from product in entities.materiaaltypes
                                 where product.materiaalType_id.Equals(materiaalType_id)
                                 select product;
            materiaaltypes huidigMateriaal = materiaalQuery.First<materiaaltypes>();
         
            // toebehoren ophalen, en ineens wegschrijven via constructor
            TypeMateriaalMetToebehoren materiaalVolledig = new TypeMateriaalMetToebehoren(GetToebehorenTypesByMateriaalTypeId(huidigMateriaal.materiaalType_id))
            {
                materiaalType_id = huidigMateriaal.materiaalType_id,
                Type = huidigMateriaal.type,
                Naam = huidigMateriaal.naam,
                Korte_naam = huidigMateriaal.korte_naam,
                Omschrijving = huidigMateriaal.omschrijving,
                Afbeelding = huidigMateriaal.afbeelding,
                File = huidigMateriaal.file,
                Waarborg = huidigMateriaal.waarborg,
                WaarborgExtraStuks = huidigMateriaal.waarborgExtraStuks,
                Dagprijs = huidigMateriaal.dagprijs
            };

            return materiaalVolledig;
        }
        /*
         * Returns 'null' wanneer de opgegeven code niet voorkomt in de tabel
         */
        public static TypeMateriaalMetToebehoren GetTypeMateriaalMetToebehorenByMateriaalScancode(String code)
        {
            var materiaalcodeQuery = from product in entities.materiaal
                                     where product.streepjescode.ToLower().Equals(code.ToLower())
                                     select product;
            List<materiaal> lijstMateriaal = materiaalcodeQuery.ToList();
            if (lijstMateriaal.Count > 0)
            {
                return GetTypeMateriaalMetToebehorengByMateriaalTypeId(lijstMateriaal.ElementAt(0).materiaalType_id);
            }
            else
            {
                return null;
            }
        }

        public static List<ontleningen> GetOntleendeProductenByAanvraagId(int aanvraag_id)
        {
            var ontleningQuery = from item in entities.ontleningen
                                 where item.aanvraag_id.Equals(aanvraag_id)
                                 select item;
            return ontleningQuery.ToList();
        }

        // return :    key toebehorentypes, value int aantal
        public static List<toebehorentypes> GetToebehorenTypesByMateriaalTypeId(int materiaalType_id)
        {
            var toebehorenMateriaalQuery = from toebehorenMateriaal in entities.toebehorenmateriaal
                                           where toebehorenMateriaal.materiaalType_id.Equals(materiaalType_id)
                                           select toebehorenMateriaal;

            var toebehorenMateriaalLijst = toebehorenMateriaalQuery.ToList();
            //Dictionary<toebehorentypes, int> resultaatLijstToebehoren = new Dictionary<toebehorentypes, int>();
            List<toebehorentypes> resultaatLijstToebehoren = new List<toebehorentypes>();

            foreach (var toebehorenMateriaal in toebehorenMateriaalLijst)
            {
                // juiste toebehoren ophalen (in het juiste AANTAL): 2 luidsprekerkabels? => luidsprekerkabel 2x toevoegen
                var toebehorenQuery = from product in entities.toebehorentypes
                                      where product.toebehorenType_id.Equals(toebehorenMateriaal.toebehorenType_id)
                                      select product;
                toebehorentypes producttype = toebehorenQuery.First();
                for (int i = 0; i < toebehorenMateriaal.aantal; i++)
                {
                    //resultaatLijstToebehoren.Add(toebehorenQuery.First<toebehorentypes>(), toebehorenMateriaal.aantal);
                    resultaatLijstToebehoren.Add(producttype);
                }
                
            }
            return resultaatLijstToebehoren;
        }

        public static toebehorentypes GetToebehorenTypeByToebehorenTypeId(int toebehorenType_id)
        {
            var toebehorenQuery = from producttype in entities.toebehorentypes
                                  where producttype.toebehorenType_id.Equals(toebehorenType_id)
                                  select producttype;
            return toebehorenQuery.First();
        }

        public static toebehorentypes GetTypeToebehorenByToebehorenScancode(String code)
        {
            var toebehorencodequery = from product in entities.toebehoren
                                      where product.streepjescode.ToLower().Equals(code.ToLower())
                                      select product;
            List<toebehoren> lijstToebehoren = toebehorencodequery.ToList();
            if (lijstToebehoren.Count > 0)
            {
                return GetToebehorenTypeByToebehorenTypeId(lijstToebehoren.ElementAt(0).toebehorenType_id);
            }
            else
            {
                return null;
            }
        }

        public static verenigingen GetVerenigingById(int id)
        {
            var verenigingQuery = from vereniging in entities.verenigingen
                                  where vereniging.vereniging_id.Equals(id)
                                  select vereniging;
            return verenigingQuery.First<verenigingen>();
        }

        public static void UpdateAanvraagStatus(int aanvraagId, Aanvraag.Statussen status)
        {
            var query = from a in entities.aanvragen
                        where a.aanvraag_id.Equals(aanvraagId)
                        select a;
            query.First().status_id = (int) status;
            entities.SaveChanges();
        }

        public static void AddOntlening(int aanvraagId, String streepjescode, int magazijnierIdAfhaling)
        {
            // alle nodige controles zijn gebeurd in OntleningsBeheerder, dus we gaan er hier van uit dat de invoer correct is...
            entities.ontleningen.AddObject(new ontleningen()
            {
                aanvraag_id = aanvraagId,
                magazijnier_id_afhaling = magazijnierIdAfhaling,
                streepjescode = streepjescode,
                tijdstip_afhaling = DateTime.Now,
                magazijnier_id_inlevering = 0,
                tijdstip_inlevering = DateTime.MinValue
            });
            //entities.SaveChanges(); // pas op het einde doen (1x naar de database schrijven)
        }

        public static void UndoAddOntlening(int aanvraagId, String streepjescode)
        {
            var ontleningQuery = from ontlening in entities.ontleningen
                                 where ontlening.streepjescode.Equals(streepjescode)
                                 && (ontlening.aanvraag_id.Equals(aanvraagId))
                                 select ontlening;
            entities.ontleningen.DeleteObject(ontleningQuery.First());                                 
        }
        // wordt vanuit gegaan dat alles OK is qua params
        public static void BeeindigOntlening(int aanvraagId, String streepjescode, int magazijnierIdInlevering)
        {
            var ontleningQuery = from ontlening in entities.ontleningen
                                 where ontlening.streepjescode.Equals(streepjescode)
                                 && ontlening.aanvraag_id.Equals(aanvraagId)
                                 select ontlening;
            ontleningen entry = ontleningQuery.First();

            entry.magazijnier_id_inlevering = magazijnierIdInlevering;
            entry.tijdstip_inlevering = DateTime.Now;
        }

        public static void UndoBeeindigingOntlening(int aanvraagId, String streepjescode)
        {
            var ontleningQuery = from ontlening in entities.ontleningen
                                 where ontlening.streepjescode.Equals(streepjescode)
                                 && ontlening.aanvraag_id.Equals(aanvraagId)
                                 select ontlening;
            ontleningen entry = ontleningQuery.First();
            entry.tijdstip_inlevering = DateTime.MinValue;
            entry.magazijnier_id_inlevering = 0;
        }


        // return true wanneer alles in orde is => werkt niet voordat entities.savechanges gedaan is....
        //public static bool ControleScancodeByAanvraag(int aanvraagId, String streepjescode)
        //{
        //    var controleQuery = from product in entities.ontleningen
        //                        where product.aanvraag_id.Equals(aanvraagId)
        //                        && product.streepjescode.Equals(streepjescode)
        //                        select product;
        //    if (controleQuery.ToList().Count == 0)
        //    {
        //        return true;
        //    }
        //    return false;
        //}

        // gaat gebruikt worden bij Ontleningen-views
        public static void OpslaanWijzigingen()
        {
            entities.SaveChanges(); // updateException bij niet unieke primary keys...
        }

        public static void SetAfhalenMagazijnier(int aanvraagId, int? magazijnier_id_afhaling)
        {
            var query = from a in entities.aanvragen
                        where a.aanvraag_id.Equals(aanvraagId)
                        select a;
            query.First().magazijnier_id_afhaling = magazijnier_id_afhaling;
            entities.SaveChanges();
        }

        public static void SetInleverenMagazijnier(int aanvraagId, int? magazijnier_id_inlevering)
        {
            var query = from a in entities.aanvragen
                        where a.aanvraag_id.Equals(aanvraagId)
                        select a;
            query.First().magazijnier_id_inlevering = magazijnier_id_inlevering;
            entities.SaveChanges();
        }

        public static void SetAfhalenTijd(int aanvraagId, DateTime geplande_afhaling)
        {
            var query = from a in entities.aanvragen
                        where a.aanvraag_id.Equals(aanvraagId)
                        select a;
            query.First().geplande_afhaling = geplande_afhaling;
            entities.SaveChanges();
        }

        public static void SetInleverenTijd(int aanvraagId, DateTime geplande_inlevering)
        {
            var query = from a in entities.aanvragen
                        where a.aanvraag_id.Equals(aanvraagId)
                        select a;
            query.First().geplande_inlevering = geplande_inlevering;
            entities.SaveChanges();
        }

        public static void SetRaadVanBestuur(int Gebruiker_id, bool lid)
        {
            SetRaadVanBestuur(Gebruiker_id, lid, Functie.Lid);
        }

        public static void SetRaadVanBestuur(int Gebruiker_id, bool lid, Functie functie)
        {
            var query = from l in entities.ledenrvbs
                        where l.gebruiker_id.Equals(Gebruiker_id) && (l.einde == new DateTime(1,1,1) || l.einde > DateTime.Now)
                        select l;
            if (query.Count() > 0 && !lid)
            {
                query.First().einde = DateTime.Now;
            }
            else if(query.Count() < 1 && lid)
            {
                entities.AddToledenrvbs(new ledenrvbs()
                {
                    gebruiker_id = Gebruiker_id,
                    start = DateTime.Now,
                    functie =  Enum.GetName(typeof(Functie), functie)
                });
            }
            entities.SaveChanges();
        }

        public static bool IsRaadVanBestuur(int Gebruiker_id)
        {
            var query = from l in entities.ledenrvbs
                        where l.gebruiker_id.Equals(Gebruiker_id) && (l.einde == new DateTime(1,1,1)  || l.einde> DateTime.Now)
                        select l;
            return (query.Count() > 0);
        }

        public static void SetAlgemeneVergadering(int Gebruiker_id, bool lid)
        {
            var query = from l in entities.ledenalgverg
                        where l.gebruiker_id.Equals(Gebruiker_id) && (l.einde == new DateTime(1, 1, 1) || l.einde > DateTime.Now)
                        select l;
            if (query.Count() > 0 && !lid)
            {
                query.First().einde = DateTime.Now;
            }
            else if (query.Count() < 1 && lid)
            {
                entities.AddToledenalgverg(new ledenalgverg()
                {
                    gebruiker_id = Gebruiker_id,
                    start = DateTime.Now
                });
            }
            entities.SaveChanges();
        }

        public static bool IsAlgemeneVergadering(int Gebruiker_id)
        {
            var query = from l in entities.ledenalgverg
                        where l.gebruiker_id.Equals(Gebruiker_id) && (l.einde == new DateTime(1, 1, 1) || l.einde > DateTime.Now)
                        select l;
            return (query.Count() > 0);
        }

        public static void SetMagazijnier(int Gebruiker_id, bool lid)
        {
            var query = from l in entities.magazijniers
                        where l.gebruiker_id.Equals(Gebruiker_id) && (l.einde == new DateTime(1, 1, 1) || l.einde == null || l.einde > DateTime.Now)
                        select l;
            if (query.Count() > 0 && !lid)
            {
                query.First().einde = DateTime.Now;
            }
            else if (query.Count() < 1 && lid)
            {
                entities.AddTomagazijniers(new magazijniers()
                {
                    gebruiker_id = Gebruiker_id,
                    start = DateTime.Now,
                    streepjescode = StreepjesCode.ConvertToStreepjesCode(StreepjesCode.CodeType.Gebruiker,Gebruiker_id)
                });
            }
            entities.SaveChanges();
        }

        public static bool IsMagazijnier(int Gebruiker_id)
        {
            var query = from l in entities.magazijniers
                        where l.gebruiker_id.Equals(Gebruiker_id) && (l.einde == new DateTime(1, 1, 1) || l.einde == null || l.einde > DateTime.Now)
                        select l;
            return (query.Count() > 0);
        }

        public static int GetAantalMateriaalDefect(int materiaalType_id)
        {
            return (from m in entities.materiaal
                    where m.materiaalType_id == materiaalType_id && m.defect
                    select m).Count();
        }

        public static int GetAantalMateriaalOntleenbaar(int materiaalType_id)
        {
            return (from m in entities.materiaal
                    where m.materiaalType_id == materiaalType_id && m.ontleenbaar
                    select m).Count();
        }

        public static int GetAantalMateriaal(int materiaalType_id)
        {
            return (from m in entities.materiaal
                    where m.materiaalType_id == materiaalType_id
                    select m).Count();
        }

        public static int GetAantalMateriaalOntleend(int MateriaalId, int Aanvraag_id)
        {
            Aanvraag av = GetAanvraagById(Aanvraag_id);
            return GetAantalMateriaalOntleend(MateriaalId, av.Evenement.start, av.Evenement.einde, av.AanvraagId);
        }

        public static int GetAantalMateriaalOntleend(int materiaalType_id, DateTime start, DateTime einde, int currentAanvraagId = 0)
        {
            var n = from m in entities.materiaalbestellingen
                    join a in entities.aanvragen on m.aanvraag_id equals a.aanvraag_id
                    join e in entities.evenement on a.evenement_id equals e.evenement_id
                    where m.materiaalType_id == materiaalType_id
                        && e.start < start
                        && e.einde > einde
                        && a.aanvraag_id != currentAanvraagId
                    select m.aantalGoedgekeurd;
            return (n.Count() >0)?n.Sum():0;
        }

        public static void SetMaterialenForAanvraagId(List<MateriaalBestelling> LijstVanMateriaalBestellingen)
        {
            Console.WriteLine("count: " + LijstVanMateriaalBestellingen.Count());
            foreach (var mb in LijstVanMateriaalBestellingen)
            {
                if (mb.MateriaalBestelling_id == 0)
                {
                    Console.WriteLine("INSERT :" + mb.MateriaalVolledig.Naam + " " + mb.MateriaalBestelling_id);
                    entities.materiaalbestellingen.AddObject(new materiaalbestellingen()
                    {
                        aantalAangevraagd = mb.AantalAangevraagd,
                        aantalGoedgekeurd = mb.AantalGoedgekeurd,
                        aanvraag_id = mb.Aanvraag_id,
                        materiaalType_id = mb.MateriaalType_id
                    });
                }
                else
                {
                    Console.WriteLine("UPDATE :" + mb.MateriaalVolledig.Naam + " " + mb.MateriaalBestelling_id);
                    var MateriaalBestellingEntities = entities.materiaalbestellingen.Where(m => m.materiaalBestelling_id == mb.MateriaalBestelling_id);
                    foreach (var m in MateriaalBestellingEntities)
                    {
                        m.materiaalType_id = mb.MateriaalType_id;
                        m.aantalAangevraagd = mb.AantalAangevraagd;
                        m.aantalGoedgekeurd = mb.AantalGoedgekeurd;
                        m.aanvraag_id = mb.Aanvraag_id;
                    }
                }
            }
            entities.SaveChanges();
        }

        public static string GetBestuursFunctieById(int Gebruiker_id)
        {
            var bestuursledenfuncties = from b in entities.ledenrvbs
                                        where b.gebruiker_id.Equals(Gebruiker_id) && (b.einde == new DateTime(1, 1, 1) || b.einde > DateTime.Now)
                                        select b.functie;
            if (bestuursledenfuncties.Count() > 0)
            {
                return bestuursledenfuncties.First().ToString();
            }
            return "";
        }

        public static Dictionary<DateTime, string> GetMagazijnierNaamAndDate(int jaartal)
        {
            var magdays = from planning in entities.planningmagazijniers
                          join mag in entities.magazijniers on planning.magazijnier_id equals mag.magazijnier_id
                          join geb in entities.gebruikers on mag.gebruiker_id equals geb.gebruiker_id
                          where planning.datum.Year == jaartal
                          select new{planning.datum, geb.voornaam, geb.naam};

            return magdays.ToDictionary(n => n.datum, n => n.naam + ' ' + n.voornaam);
        }

        public static bool PlanningBestaat(DateTime datum)
        {
            var aantalBestaandePlanningen = (from p in entities.planningmagazijniers
                                             where p.datum == datum
                                             select p).Count();
            return (aantalBestaandePlanningen>0);
        }

        internal static void SetBestuurdersFunctieById(int Gebruiker_id, Functie functie)
        {
            var best = (from b in entities.ledenrvbs
                        where b.gebruiker_id == Gebruiker_id
                        select b);
            var latest = from b in best
                         where b.start == best.Max(be => be.start)
                         select b;
            if (latest.Count() > 0)
            {
                ledenrvbs lid = latest.First();
                if (lid.einde == DateTime.MinValue || lid.einde > DateTime.Now)
                {
                    lid.functie = Enum.GetName(typeof(Functie), functie);
                    entities.SaveChanges();
                }
            }
        }



        internal static List<toebehorentypes> GetAllToebehorenTypes()
        {
            var toebehorentypes = from t in entities.toebehorentypes select t;
            return toebehorentypes.ToList();
        }

        internal static void AddMateriaal(materiaal materiaal)
        {
            entities.AddTomateriaal(materiaal);
            entities.SaveChanges();
        }

        internal static void AddToebehoren(toebehoren toebehoren)
        {
            entities.AddTotoebehoren(toebehoren);
            entities.SaveChanges();
        }

        internal static bool StreepjescodeExists(string code)
        {
            int aantal=0;
            code = code.ToLower();
            if (code.Length == 5)
            {
                if (code[0] == 'm')
                {
                    aantal = (from m in entities.materiaal
                              where m.streepjescode.ToLower() == code
                              select m).Count();
                }
                if (code[0] == 't')
                {
                    aantal = (from m in entities.toebehoren
                              where m.streepjescode.ToLower() == code
                              select m).Count();
                }
                if (code[0] == 'g')
                {
                    aantal = (from m in entities.magazijniers
                              where m.streepjescode.ToLower() == code
                              select m).Count();
                }
            }
            return (aantal > 0);
        }

        internal static materiaal GetMateriaalByScancode(string c)
        {
            var mq = from m in entities.materiaal
                     where m.streepjescode == c
                     select m;
            if (mq.Count() > 0) return mq.First();
            else return null;
        }
        internal static toebehoren GetToebehorenByScancode(string c)
        {
            var mq = from m in entities.toebehoren
                     where m.streepjescode == c
                     select m;
            if (mq.Count() > 0) return mq.First();
            else return null;
        }

        internal static void SwitchCode(materiaal oldMateriaal, string c)
        {
            var ontl = from o in entities.ontleningen
                       where o.streepjescode.ToLower() == oldMateriaal.streepjescode.ToLower()
                       select o;
            foreach (var o in ontl) o.streepjescode = c;

            entities.DeleteObject(oldMateriaal);
            entities.AddTomateriaal(new materiaal()
            {
                defect = oldMateriaal.defect,
                materiaalType_id = oldMateriaal.materiaalType_id,
                ontleenbaar = oldMateriaal.ontleenbaar,
                streepjescode = c
            });
            entities.SaveChanges();
        }
        internal static void SwitchCode(toebehoren oldToebehoren, string c)
        {
            var ontl = from o in entities.ontleningen
                       where o.streepjescode.ToLower() == oldToebehoren.streepjescode.ToLower()
                       select o;
            foreach (var o in ontl) o.streepjescode = c;
            entities.DeleteObject(oldToebehoren);
            entities.AddTotoebehoren(new toebehoren()
            {
                defect = oldToebehoren.defect,
                toebehorenType_id = oldToebehoren.toebehorenType_id,
                streepjescode = c
            });
            entities.SaveChanges();
        }
    }
}
